#pragma once

#include <iostream>
#include <memory>
#include <string>
#include <unordered_map>
#include <unistd.h>
#include <cstdint>
#include <sstream>
#include "TcpServer.hpp"
#include "InetAddr.hpp"
#include "Log.hpp"
#include "Socket.hpp"
#include "Util.hpp"

using namespace LogModule;
using namespace SocketModule;

const std::string gspace = " ";
const std::string glinespace = "\r\n";
const std::string glinesep = ": "; // 报头内存储为  Key:[空格]value

const std::string webroot = "./wwwroot";
const std::string homepage = "index.html";

class HttpRequest
{
public:
    HttpRequest()
    {
    }
    void ParseReqLine(std::string &reqline)
    {
        std::stringstream ss(reqline);
        // 读取一个词（以空白字符分隔），并将其存储到 _method 等字符串变量中
        ss >> _method >> _uri >> _version;
    }

    bool Deserialize(std::string &reqstr)
    {
        // 1. 获取请求行
        std::string reqline;
        Util::ReadOneLine(reqstr, &reqline, glinespace);
        LOG(LogLevel::DEBUG) << reqline;

        // 2. 对请求行进行反序列化
        ParseReqLine(reqline);

        // 此时请求行已经解析完成
        LOG(LogLevel::DEBUG) << "_method: " << _method;
        LOG(LogLevel::DEBUG) << "_uri: " << _uri;
        LOG(LogLevel::DEBUG) << "_version: " << _version;

        if ("/" == _uri)
        {
            _uri = webroot + _uri + homepage;
        }
        else
        {
            _uri = webroot + _uri;
        }
    }

    std::string Uri()
    {
        return _uri;
    }

    ~HttpRequest() {}

private:
    std::string _method;
    std::string _uri;
    std::string _version;

    std::unordered_map<std::string, std::string> _header;
    std::string _blankline;
    std::string _text;
};

class HttpResponse
{
public:
    HttpResponse()
    {
    }
    void SetTargetFile(const std::string &target)
    {
        _targetfile = target;
    }
    bool MakeResponse()
    {
        bool res = Util::ReadFileContent(_targetfile, &_text);
        if(!res)
        {
            _code = 404;
            _desc = "Not Found";

            return false;
        }
 
        return true;
    }
    std::string Serialize()
    {
        // 状态行
        std::string status_line = _version + gspace + _code + gspace + _desc + glinespace; // todo
    }

private:
    std::string _version;
    int _code;
    std::string _desc;

    std::unordered_map<std::string, std::string> _headers;
    std::string blankline;
    std::string _text;

    std::string _targetfile;
};

class Http
{
public:
    Http(uint16_t port)
        : tsverp(std::make_unique<TcpServer>(port))
    {
    }
    void HandlerHttpRquest(std::shared_ptr<SocketModule::Socket> &sock, InetAddr &client)
    {
        std::string httpreqstr;
        int n = sock->Recv(&httpreqstr);
        if (n > 0)
        {
            HttpRequest req;
            req.Deserialize(httpreqstr);

            HttpResponse resp;
            resp.SetTargetFile(req.Uri());
        }
    }

    void Start()
    {
        tsverp->Start([this](std::shared_ptr<SocketModule::Socket> &sock, InetAddr &client)
                      { this->HandlerHttpRquest(sock, client); });
    }

private:
    std::unique_ptr<TcpServer> tsverp;
};